package com.bosssoft.setp.handler;

import com.bosssoft.setp.model.business.shop.TrainingPlace;
import org.springframework.stereotype.Service;
import xyz.erupt.annotation.fun.DataProxy;
import xyz.erupt.core.exception.EruptApiErrorTip;
import xyz.erupt.jpa.dao.EruptDao;

import javax.annotation.Resource;
import java.util.List;
import java.util.regex.Pattern;

/**
 * 该类是针对 TrainingPlace 实体的数据代理类，用于在数据内容变更时进行验证。
 *
 * @author lin-gaoying
 * @version 1.0
 * @since 1.0
 */
@Service
public class TrainingPlaceProxy implements DataProxy<TrainingPlace> {

    private static final int  SINGLE_DIGIT = 10;
    private static final int  DOUBLE_DIGIT = 100;


    @Resource
    private EruptDao eruptDao;

    /**
     * 验证手机号和邮箱的格式是否正确。
     * 该方法在添加培训地点信息前进行调用，确保提供的手机号和邮箱符合规定的格式。
     *
     * @param trainingPlace 待添加的培训地点对象，包含需要验证的手机号和邮箱信息。
     */
    @Override
    public void beforeAdd(TrainingPlace trainingPlace) {
        String phoneNumber = trainingPlace.getPhoneNumber();
        String mailbox = trainingPlace.getMailbox();

        if (phoneNumber != null && !phoneNumber.isEmpty()) {
            boolean matches = Pattern.matches(
                    "^1[3-9]\\d{9}$|" +
                            "^1[3-9]\\d{1}[-\\s]\\d{4}[-\\s]\\d{4}$|" +
                            "^\\(1[3-9]\\d{1}\\)\\d{4}-\\d{4}$|" +
                            "^(?:\\(\\+\\d{2}\\)|\\+\\d{2})(\\d{11})$|" +
                            "^0\\d{3}-\\d{7}$|" +
                            "^0\\d{2}-\\d{8}$", phoneNumber);
            if (!matches) {
                throw new EruptApiErrorTip("请输入正确的手机号！");
            }
        }

        if (mailbox != null && !mailbox.isEmpty()) {
            boolean matches = Pattern.matches(
                    "^(\\w+([-.][A-Za-z0-9]+)*){3,18}@\\w+" +
                            "([-.][A-Za-z0-9]+)*\\.\\w+" +
                            "([-.][A-Za-z0-9]+)*$", mailbox);
            if (!matches) {
                throw new EruptApiErrorTip("请输入正确的邮箱！");
            }
        }

    }

    /**
     * 该方法在添加培训地点信息后进行调用，用于自动生成实体编号属性。
     *
     * @param trainingPlace 待添加的培训地点对象，包含需要验证的手机号和邮箱信息。
     */
    @Override
    public void afterAdd(TrainingPlace trainingPlace) {

        if (trainingPlace.getTrainingPlace() != null) {
            trainingPlace.setParentId(trainingPlace.getTrainingPlace().getId());

            List<TrainingPlace> list = eruptDao.lambdaQuery(TrainingPlace.class)
                    .eq(TrainingPlace::getParentId, trainingPlace.getParentId())
                    .ne(TrainingPlace::getId, trainingPlace.getId())
                    .list();

            String sql = "SELECT number FROM setp_training_place WHERE id = ?";
            String number = eruptDao.getJdbcTemplate().queryForObject(
                    sql, String.class, trainingPlace.getParentId());

            int size = list.size() + 1;
            if (size < SINGLE_DIGIT) {
                trainingPlace.setNumber(number + "-00" + size);
            } else if (size < DOUBLE_DIGIT) {
                trainingPlace.setNumber(number + "-0" + size);
            } else {
                trainingPlace.setNumber(number + "-" + size);
            }

        } else {
            List<TrainingPlace> list = eruptDao.lambdaQuery(TrainingPlace.class)
                    .eq(TrainingPlace::getAlianceBusiness, trainingPlace.getAlianceBusiness())
                    .ne(TrainingPlace::getId, trainingPlace.getId())
                    .list();

            Long number = trainingPlace.getAlianceBusiness().getId();
            int size = list.size() + 1;

            if (size < SINGLE_DIGIT) {
                trainingPlace.setNumber(number + "-00" + size);
            } else if (size < DOUBLE_DIGIT) {
                trainingPlace.setNumber(number + "-0" + size);
            } else {
                trainingPlace.setNumber(number + "-" + size);
            }
        }

    }

    /**
     * 验证手机号和邮箱的格式是否正确。
     * 该方法在添加培训地点信息前进行调用，确保提供的手机号和邮箱符合规定的格式。
     *
     * @param trainingPlace 待添加的培训地点对象，包含需要验证的手机号和邮箱信息。
     */
    @Override
    public void beforeUpdate(TrainingPlace trainingPlace) {
        String phoneNumber = trainingPlace.getPhoneNumber();
        String mailbox = trainingPlace.getMailbox();

        if (phoneNumber != null && !phoneNumber.isEmpty()) {
            boolean matches = Pattern.matches(
                    "^1[3-9]\\d{9}$|" +
                            "^1[3-9]\\d{1}[-\\s]\\d{4}[-\\s]\\d{4}$|" +
                            "^\\(1[3-9]\\d{1}\\)\\d{4}-\\d{4}$|" +
                            "^(?:\\(\\+\\d{2}\\)|\\+\\d{2})(\\d{11})$|" +
                            "^0\\d{3}-\\d{7}$|" +
                            "^0\\d{2}-\\d{8}$", phoneNumber);
            if (!matches) {
                throw new EruptApiErrorTip("请输入正确的手机号！");
            }
        }

        if (mailbox != null && !mailbox.isEmpty()) {
            boolean matches = Pattern.matches(
                    "^(\\w+([-.][A-Za-z0-9]+)*){3,18}@\\w+" +
                            "([-.][A-Za-z0-9]+)*\\.\\w+" +
                            "([-.][A-Za-z0-9]+)*$", mailbox);
            if (!matches) {
                throw new EruptApiErrorTip("请输入正确的邮箱！");
            }
        }

    }

    /**
     * 该方法在更新培训地点信息后进行调用，用于自动生成实体编号属性。
     *
     * @param trainingPlace 待添加的培训地点对象，包含需要验证的手机号和邮箱信息。
     */
    @Override
    public void afterUpdate(TrainingPlace trainingPlace){
        if (trainingPlace.getTrainingPlace() != null) {
            trainingPlace.setParentId(trainingPlace.getTrainingPlace().getId());

            List<TrainingPlace> list = eruptDao.lambdaQuery(TrainingPlace.class)
                    .eq(TrainingPlace::getParentId, trainingPlace.getParentId())
                    .ne(TrainingPlace::getId, trainingPlace.getId())
                    .list();

            String sql = "SELECT number FROM setp_training_place WHERE id = ?";
            String number = eruptDao.getJdbcTemplate().queryForObject(
                    sql, String.class, trainingPlace.getParentId());

            int size = list.size() + 1;
            if (size < SINGLE_DIGIT) {
                trainingPlace.setNumber(number + "-00" + size);
            } else if (size < DOUBLE_DIGIT) {
                trainingPlace.setNumber(number + "-0" + size);
            } else {
                trainingPlace.setNumber(number + "-" + size);
            }

        } else {
            List<TrainingPlace> list = eruptDao.lambdaQuery(TrainingPlace.class)
                    .eq(TrainingPlace::getAlianceBusiness, trainingPlace.getAlianceBusiness())
                    .ne(TrainingPlace::getId, trainingPlace.getId())
                    .list();

            Long number = trainingPlace.getAlianceBusiness().getId();
            int size = list.size() + 1;

            if (size < SINGLE_DIGIT) {
                trainingPlace.setNumber(number + "-00" + size);
            } else if (size < DOUBLE_DIGIT) {
                trainingPlace.setNumber(number + "-0" + size);
            } else {
                trainingPlace.setNumber(number + "-" + size);
            }
        }
    }

    /**
     * 验证当前数据是否关联着其它数据。
     * 该方法在删除培训地点信息前进行调用，确保当前数据并不关联着子门店。
     *
     * @param trainingPlace 待添加的培训地点对象，包含需要验证的手机号和邮箱信息。
     */
    @Override
    public void beforeDelete(TrainingPlace trainingPlace) {
        String sql = "SELECT COUNT(*) FROM setp_training_place WHERE parent_id = ?";
        Long count = eruptDao.getJdbcTemplate().queryForObject(
                sql, Long.class, trainingPlace.getId());
        if (count > 0) {
            throw new EruptApiErrorTip("删除失败！当前门店还关联着其它子门店。");
        }

        String sql1 = "SELECT COUNT(*) FROM setp_shop_member WHERE training_place_id = ?";
        Long count1 = eruptDao.getJdbcTemplate().queryForObject(
                sql1, Long.class, trainingPlace.getId());
        if (count1 > 0) {
            throw new EruptApiErrorTip("删除失败！当前门店旗下关联有人员。");
        }
    }

}
